#include "ScriptFunctionFactory.h"

#include <QAction>

#include "ScriptGuiFactory.h"
#include "ScriptEngine.h"
#include "QtTimerService.h"
#include "ScriptActionTrigger.h"
#include "ApplicationIcon.h"


/**
 * @class ScriptFunctionFactory
 * This factory builds an HTML viewer with all optimizations useful
 * for script management, (automatic scroll, light and media action
 * recognition, launching and editing, etc...).
 *
 * Note that the engine requires the output from GUI factory, and this
 * is because engine operation depends on the content of text viewer,
 * that in Qt framework is a GUI
 */

ScriptFunctionFactory::ScriptFunctionFactory(QObject *parent) :
   QObject(parent)
{
}

ScriptEngine *ScriptFunctionFactory::build(QWidget *container, QAbstractListModel *mediaModel,
                                           QAbstractListModel *lightModel)
{
   ScriptActionTrigger *actionTrigger = new ScriptActionTrigger( this);

   ScriptGuiFactory *guiFactory = new ScriptGuiFactory( container);
   IF_ScriptViewerInterface *viewer = guiFactory->build( container, actionTrigger,
                                                         mediaModel, lightModel);

   QtTimerService *timerService = new QtTimerService( this);

   ScriptEngine *engine = new ScriptEngine( *viewer, *timerService, this);
   QList<QAction *> menuActions = createEngineActions( engine);

   connect( engine, SIGNAL(addLightEventRequest()), viewer, SLOT(addLightEvent()) );
   connect( engine, SIGNAL(addMediaEventRequest()), viewer, SLOT(addMediaEvent()) );

   viewer->setMenuActionList( menuActions);

   connect( viewer, SIGNAL(textChanged()), engine, SIGNAL(textChanged()) );

   connect( actionTrigger, SIGNAL(activateLight(QString,bool)),
            engine, SIGNAL(activateLight(QString,bool)) );

   connect( actionTrigger, SIGNAL(activateMedia(QString,bool)),
            engine, SIGNAL(activateMedia(QString,bool)) );

   connect( actionTrigger, SIGNAL(activatePicture(QString,bool)),
            engine, SIGNAL(activatePicture(QString,bool)) );

   connect( engine, SIGNAL(newSearchPath(QString)), viewer, SLOT(addSearchPath(QString)) );

   return engine;
}

QList<QAction *> ScriptFunctionFactory::createEngineActions( ScriptEngine *engine)
{
   QList<QAction *> * actionList = new QList<QAction *>();

   QAction * scriptPlay = new QAction( QIcon(IconPath("script_play.png")),
                                       tr("&play autoscroll"), this);
   scriptPlay->setShortcut( QString("P"));
   scriptPlay->setEnabled( true);
   connect( scriptPlay, SIGNAL(triggered()), engine, SLOT(playScrollAnimation()) );

   QAction * scriptPause = new QAction( QIcon(IconPath("script_pause.png")),
                                        tr("&pause autoscroll"), this);
   scriptPause->setShortcut( QString("P"));
   scriptPause->setEnabled( false);
   connect( scriptPause, SIGNAL(triggered()), engine, SLOT(pauseScrollAnimation()) );

   connect( engine, SIGNAL(scriptIsAnimated(bool)), scriptPlay, SLOT(setDisabled(bool)) );
   connect( engine, SIGNAL(scriptIsAnimated(bool)), scriptPause, SLOT(setEnabled(bool)) );

   QAction * scriptSetEdit = new QAction( QIcon(IconPath("script_edit.png")),
                                          tr("&set edit mode"), this);
   scriptSetEdit->setShortcut( QString("Ctrl+E"));
   scriptSetEdit->setCheckable( true);
   scriptSetEdit->setChecked( false);
   connect( scriptSetEdit, SIGNAL(triggered(bool)), engine, SLOT(setEditMode(bool)) );


   QAction * scriptAddLightEvent = new QAction( QIcon(IconPath("light.png")), tr("add &light event"), this);
   scriptAddLightEvent->setEnabled( false);
   connect( scriptAddLightEvent, SIGNAL(triggered()), engine, SIGNAL(addLightEventRequest()) );
   connect( scriptSetEdit, SIGNAL(triggered(bool)), scriptAddLightEvent, SLOT(setEnabled(bool)) );

   QAction * scriptAddMediaEvent = new QAction( QIcon(IconPath("sound.png")), tr("add &media event"), this);
   scriptAddMediaEvent->setEnabled( false);
   connect( scriptAddMediaEvent, SIGNAL(triggered()), engine, SIGNAL(addMediaEventRequest()) );
   connect( scriptSetEdit, SIGNAL(triggered(bool)), scriptAddMediaEvent, SLOT(setEnabled(bool)) );

   *actionList << scriptPlay << scriptPause << scriptAddMediaEvent
              << scriptAddLightEvent << scriptSetEdit;

   engine->setActionList( actionList);

   return *actionList;
}
